package com.touchwisdom.modular.common.service;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.criterion.Criterion;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.touchwisdom.modular.common.dao.HibernateDao;
import com.touchwisdom.modular.common.dao.PropertyFilter;
import com.touchwisdom.modular.common.entity.BaseEntity;
import com.touchwisdom.modular.common.system.user.UserContext;
import com.touchwisdom.modular.util.config.Page;

/**
 * 通用业务类的抽象方法，提供常用的方法实现 <BR>
 * 继承此类的子类只需要实现getHibernateDao方法即可
 * 
 * @filename CommonService.java
 * @date 2012-3-6 下午12:09:10
 * @author ggeagle
 * 
 */
@Service
@Transactional(propagation = Propagation.NESTED)
public abstract class CommonService<T extends BaseEntity, PK extends Serializable> {
	/**
	 * 用户会话
	 */
	protected UserContext userContext;

	@Resource
	public void setUserContext(UserContext userContext) {
		this.userContext = userContext;
	}

	protected abstract HibernateDao<T, PK> getHibernateDao();

	/**
	 * 保存通用对象信信息
	 * 
	 * @param entity
	 */
	public void saveEntity(T entity) {
		if (StringUtils.isBlank(entity.getId()) && entity.getCreateTime() == null) {
			entity.setCreateTime(new Date());
		}
		if (StringUtils.isBlank(entity.getId())) {
			entity.setId(null);
		}
		if (StringUtils.isNotBlank(this.userContext.currentUserId())) {
			entity.setLastUpdateUserId(this.userContext.currentUserId());
		}
		entity.setLastUpdateTime(new Date());
		this.getHibernateDao().save(entity);
	}

	/**
	 * 批量保存对象信息列表
	 * 
	 * @param list
	 */
	public void saveEntityList(List<T> list) {
		for (T entity : list) {
			this.saveEntity(entity);
		}
	}

	public void deleteEntity(T entity) {
		this.getHibernateDao().delete(entity);
	}

	public void deleteEntity(PK pk) {
		this.getHibernateDao().delete(pk);
	}

	public Page<T> findByPage(Page<T> page, List<PropertyFilter> filters) {
		return this.getHibernateDao().findPage(page, filters);
	}

	public Page<T> findByPage(Page<T> page, Criterion... criterions) {
		return this.getHibernateDao().findPage(page, criterions);
	}

	public Page<T> findByPage(Page<T> page, String hql, Object... values) {
		return this.getHibernateDao().findPage(page, hql, values);
	}

	public List<T> findList(List<PropertyFilter> filters) {
		return this.getHibernateDao().find(filters);
	}

	public List<T> findList(Criterion... criterions) {
		return this.getHibernateDao().find(criterions);
	}

	public List<T> findList(String hql, Object... values) {
		return this.getHibernateDao().find(hql, values);
	}

	public void deleteEntityList(PK[] ids) {
		for (PK id : ids) {
			this.getHibernateDao().delete(id);
		}
	}

	/**
	 * 批量删除数组中的元素
	 * 
	 * @param arrays
	 */
	public void deleteEntityList(T[] arrays) {
		for (T t : arrays) {
			this.getHibernateDao().delete(t);
		}
	}

	/**
	 * 批量删除集合中的元素
	 * 
	 * @param lists
	 */
	public void deleteEntityList(List<T> lists) {
		for (T t : lists) {
			this.getHibernateDao().delete(t);
		}
	}

	/**
	 * 返回全部的对象信息列表
	 * 
	 * @return 合部对象列表
	 */
	public List<T> getAll() {
		return this.getHibernateDao().getAll();
	}

	/**
	 * 根据对象的主键得到对象
	 * 
	 * @param id
	 *            对象的主键
	 * @return
	 */
	public T getEntity(PK id) {
		return this.getHibernateDao().get(id);
	}
}